﻿using Bentley.CifNET.Formatting;
using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.Elements;
using Bentley.MstnPlatformNET;
using CulvertInitializationDatas;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace CheccCoverplateCulvertAssemble.Conmmon
{
    internal class GeneralHelpers
    {
        public static string WorkSpacePath => ConfigurationManager.GetVariable("Checc_CulvertCustomPath") == null ? "C:\\Program Files\\CCCCLTD\\Highway BIM Solution\\ZJCulvert\\Resources\\" : ConfigurationManager.GetVariable("Checc_CulvertCustomPath");
        public static string LevelAndMatrialJsonFilePath = $@"{ConfigurationManager.GetVariable("Checc_CulvertCustomPath")}\Standards\涵洞\涵洞_属性图层材质设置_当前值.ini";
        public static string SeedFilePath => ConfigurationManager.GetVariable("MS_SEEDFILES");
        public static DgnFile ActiveDgnFile => Session.Instance.GetActiveDgnFile();
        public static DgnModel ActiveDgnModel => Session.Instance.GetActiveDgnModel();
        public static DgnModel Default3DModel => Session.Instance.GetActiveDgnFile().FindLoadedModelById(Session.Instance.GetActiveDgnFile().FindModelIdByName("Default-3D"));

        public static DgnModel DefaultModel => Session.Instance.GetActiveDgnFile().FindLoadedModelById(Session.Instance.GetActiveDgnFile().FindModelIdByName("Default"));

        public static double UnitsToMeters = FormatSettingsConstants.GetMasterUnitsToMeters();
        public static double UorToMeters = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster;

        private static Data serializeDatas;

        /// <summary>
        /// 材质属性数据
        /// </summary>
        public static Data SerializeDatas
        {
            get
            {
                if (serializeDatas == null)
                    serializeDatas = JsonConvert.DeserializeObject<Data>(File.ReadAllText(GeneralHelpers.LevelAndMatrialJsonFilePath));

                return serializeDatas;
            }
            //set { serializeDatas = value; }
        }


        public static bool IsContainPureString(string expression, List<(string standardName, string standValue)> standValueList)
        {
            bool ret = false;
            var matchs = Regex.Split(expression, @"\(|\)|\+|\-|\*|\/").Where(s => s != "");
            foreach (var item in matchs)
            {

                if (!double.TryParse(item, out _))
                {
                    ret = true;
                    break;
                }
            }
            return ret;
        }
        public static string ConvertFormula(string expression, List<(string standardName, string standValue)> tuples)
        {
            var matchs = Regex.Split(expression, @"\(|\)|\+|\-|\*|\/").Where(s => s != "");
            foreach (var item in matchs)
            {
                var obj = tuples.FirstOrDefault(p => p.standardName.ToLower() == item.ToLower());
                if ((null, null) == obj)
                {
                    continue;
                }
                expression = expression.Replace(item, null == obj.standValue ? "" : obj.standValue);
            }
            return expression;
        }
        public static double GetWeightPerMeterOfRebar(string rebarGrade, double diameter, string rebarConfigJsonFilePath)
        {
            string jsonString = File.ReadAllText(@rebarConfigJsonFilePath);
            var objRebarConfig = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(jsonString);
            var rebarBaseInfoList = objRebarConfig[rebarGrade] as JArray;
            var weightPerMeter = rebarBaseInfoList.First(p => p["nominalDiameter"].Value<double>() == diameter)["weightPerMeter"];
            return Convert.ToDouble(weightPerMeter.ToString());
        }
        private static LevelId? CreateLevelByName(string levelName)
        {
            FileLevelCache fileLevelCache = GeneralHelpers.ActiveDgnFile.GetLevelCache();
            fileLevelCache.Write();
            LevelHandle levelHandle = fileLevelCache.GetLevelByName(levelName);
            if (!levelHandle.IsValid)
            {
                EditLevelHandle editLevelHandle = fileLevelCache.CreateLevel(levelName);
                fileLevelCache.Write();
                return editLevelHandle.LevelId;
            }
            return levelHandle.LevelId;
        }
        public static List<string> GetAllMaterialName()
        {
            var s = MaterialManager.GetPalettesInSearchPath("MS_MATERIAL").ToList();
            PaletteInfo paletteInfo = MaterialManager.GetPalettesInSearchPath("MS_MATERIAL").ToList().FirstOrDefault(p => p.Name == "CHECC_Materials");
            var materials = MaterialManager.FindMaterialsInPalette(out MaterialSearchStatus status, paletteInfo, Session.Instance.GetActiveDgnModel(), true).ToList();

            return materials.Select(m => m.Name).ToList();
        }
        private static Material GetMaterialIdByName(string materialName)
        {
            PaletteInfo paletteInfo = MaterialManager.GetPalettesInSearchPath("MS_MATERIAL").ToList().FirstOrDefault(p => p.Name == "CHECC_Materials");
            var materials = MaterialManager.FindMaterialsInPalette(out MaterialSearchStatus status, paletteInfo, Session.Instance.GetActiveDgnModel(), true).ToList();
            var material = materials.FirstOrDefault(m => m.Name == materialName);
            return material;
        }

        public static void AssignLevelToElement(Element element, string levelName)
        {
            var elementPropertiesSetter = new ElementPropertiesSetter();
            var levelId = CreateLevelByName(levelName);
            elementPropertiesSetter.SetLevel((LevelId)levelId);
            elementPropertiesSetter.Apply(element);
        }
        public static void AssignMaterialToElement(Element element, string materialName)
        {
            //if (materialName == null) return;

            //MaterialId id = new MaterialId(materialName);//查找名为Pavers BC2的材料
            //MaterialPropertiesExtension propertiesExtension = MaterialPropertiesExtension.GetAsMaterialPropertiesExtension(element as DisplayableElement);//为拉伸实体元素设置材料属性 
            //propertiesExtension.AddMaterialAttachment(id);//添加嵌入的材料信息
            //propertiesExtension.StoresAttachmentInfo(id);//保存拉伸实体元素的材料信息 
            //propertiesExtension.ReplaceInModel(element);//替换实体
            //Session.Instance.GetActiveDgnFile().SetFullSaveFlag();
            var material = GetMaterialIdByName(materialName);
            if (material == null) return;

            var materialId = new MaterialId(material.Name);
            var displayableElement = element as DisplayableElement;
            var materialPropertiesExtension = displayableElement.GetAsMaterialPropertiesExtension();
            BentleyStatus bentleyStatus = materialPropertiesExtension.AddMaterialAttachment(materialId);
            BentleyStatus bentleyStatus2 = materialPropertiesExtension.AttachSubEntityMaterial(new string[] { "Face" }, materialId);
            StatusInt ret = materialPropertiesExtension.ReplaceInModel(element);
        }

        /// <summary>
        /// 获取CSV数据
        /// </summary>
        /// <param name="filName">文件名</param>
        /// <returns></returns>
        public static Dictionary<string, string> GetCSVDatas(string filName)
        {
            //材质属性数据
            Data serializeDatas = JsonConvert.DeserializeObject<Data>(File.ReadAllText(GeneralHelpers.LevelAndMatrialJsonFilePath));
            string path = GeneralHelpers.WorkSpacePath + serializeDatas.SlabCulvertFiles[0] + @"\盖板涵_" + filName + "_构造体.csv";
            Dictionary<string, string> result = new Dictionary<string, string>();
            using (StreamReader sr = new StreamReader(path, Encoding.Default))
            {
                while (!sr.EndOfStream)
                {
                    string lineData = sr.ReadLine();

                    string[] strings = lineData.Split(',');
                    result.Add(strings[0], strings[2]);
                }
            }
            return result;
        }
    }
}
